# -*- coding: utf-8 -*-


import httplib
import urllib
try:
	import json
except ImportError:
	import simplejson as json
import random
import tempfile
import re
import htmllib
from time import sleep

from genname import genname






raw_headers = '''
Host: vkontakte.ru
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.10) Gecko/20100915 Ubuntu/10.04 (lucid) Firefox/3.6.10
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Pragma: no-cache
Cache-Control: no-cache
'''
HEADERS = {}
for i in raw_headers.strip('\n').splitlines():
	k, v = i.split(': ', 1)
	HEADERS[k] = v





class VkontakteParser:
	def __init__(self):
		self.name_re = re.compile('<b id="performer[0-9]+">(.*?)</b>.*?<span id="title[0-9]+">(.*?)</span>')
		self.location_re = re.compile('''class="playimg" onclick="return operate\(([0-9]+),([0-9]+),([0-9]+),'(.*?)',([0-9]+)\)''')
		self.duration_re = re.compile('<div class="duration">(.*?)</div>')
		self.entries_found_re = re.compile('''<div id="searchSummary" class="summary">(.*?)</div>''')
		
		self.html = re.compile(r'<.*?>')
	
	def _html_unescape(self, s):
		p = htmllib.HTMLParser(None)
		p.save_bgn()
		p.feed(s)
		return p.save_end()


	def parse(self, resp):
		#open('test.html', 'w').write(resp)
		
		names = self.name_re.findall(resp)
		locations = self.location_re.findall(resp)
		durations = self.duration_re.findall(resp)
		#entries = self.entries_found_re.findall(resp)[0]
		#assert False, entries
		
		assert len(durations) == len(locations) == len(names)
		
		for name, location, duration in zip(names, locations, durations):
			retval = {}
			l = location
			retval['url'] = "http://cs"+l[1]+".vkontakte.ru/u"+l[2]+"/audio/"+l[3]+".mp3"
			#retval['mp3_key'] = (l[1], l[2], l[3])
			artist, title = name
			retval['title'] = self._html_unescape(self.html.sub('', title))
			retval['artist'] = self._html_unescape(self.html.sub('', artist))
			retval['duration'] = duration
			yield retval
parse = VkontakteParser().parse





class Vkontakte:

	def __init__(self, headers=HEADERS):
		self.headers = headers	
	
	def _get_register_data(self):
		data = {}
		data['firstname'] = genname()
		data['lastname'] = genname()
		m = data['firstname'] + '19' + str(random.randint(7, 9)) + str(random.randint(0, 9))
		data['email'] = (m + '@' + random.choice(['gmail', 'hotmail', 'yahoo']) + random.choice(['.com', '.ru'])).lower()
		data['password'] = ''.join(str(random.randint(0, 9)) for i in range(random.randint(7, 10)))
		data['gender'] = random.choice([True, False])
		return data


	def _register(self, captcha_sid="", captcha_key=""):
		register = self._get_register_data()
		data = urllib.urlencode(dict(
			act='register',
			timezone='120',
			by_login='0',
			captcha_sid=captcha_sid,
			captcha_key=captcha_key,
			first_name=register['email'],
			last_name=register['lastname'],
			regemail=register['email'],
			regpass=register['password']
		))
		conn = httplib.HTTPConnection('vkontakte.ru')
		conn.request('POST', '/register.php', data, self.headers)
		resp = conn.getresponse().read()
		print resp
		return json.loads(resp)

	
	def register(self, captcha_cb):
		resp = self._register()
		while True:
			captcha_sid = resp['captcha_sid']
			captcha_url = 'http://vkontakte.ru/captcha.php?sid='+captcha_sid
			captcha_response = captcha_cb(captcha_url)
			if captcha_response is None:
				return
			resp = self._register(captcha_sid=captcha_sid, captcha_key=captcha_response)
			#print resp
			if 'mail' in resp and 'pass' in resp:
				break
		pwd = resp['pass']
		email = resp['mail'] 
		
		self.login(email, pwd)
		
		sleep(0.2)
		
		conn = httplib.HTTPConnection('vkontakte.ru')
		conn.request('GET', '/regstep3', headers=self.headers)
		resp = conn.getresponse().read()
		
		#open('test.html', 'w').write(resp)
		finish_link = re.findall('<a href="(.*?)" id="finish_link"', resp)[0]
		
		sleep(0.2)
		
		conn = httplib.HTTPConnection('vkontakte.ru')
		conn.request('GET', finish_link, headers=self.headers)
		#resp = conn.getresponse().read()
		
		#in some cases the user is not activated (i really dont know why)
		if not list(self.search('dj')):
			print 'no search results found, creating another account'
			return self.register(captcha_cb)
		
		
		return email, pwd

	def login(self, email, pwd):
		data = 'pass='+urllib.quote(pwd)+'&email='+urllib.quote(email)
		conn = httplib.HTTPConnection('vkontakte.ru')
		conn.request('POST', '/login.php', data, self.headers)
		resp_obj = conn.getresponse()
		
		cookie = dict(resp_obj.getheaders())['set-cookie']
		try:
			remixsid = re.findall('remixsid=(.*?);', cookie)[0]
		except IndexError:
			raise ValueError('false login')
		self.headers['Cookie'] = "remixchk=5; remixsid=" + remixsid
	
	
	def search(self, query, page_nr=0): #TODO select page nr
		
		conn = httplib.HTTPConnection('vkontakte.ru')
		conn.request('GET', '/gsearch.php?section=audio&q='+urllib.quote_plus(query)+'&offset='+str(page_nr*100), headers=self.headers)
		resp = conn.getresponse().read()
		#open('test.html', 'w').write(resp)
		return parse(resp)
	
	
	#def fastsearch(self, query):
	#	conn = httplib.HTTPConnection('vkontakte.ru')
	#	conn.request('POST', '/hints.php', 'act=a_gsearch_hints&section=people&q='+query, self.headers)
	#	resp = conn.getresponse().read()
	#	
	#	return resp
		
		
		
if __name__ == '__main__':
	vk = Vkontakte()
	vk.login('bla@hotmail.com', 'blub')
	print list(vk.search('test'))
	



